import logging, re
from QQLoginTool.QQtool import OAuthQQ
from django import http
from django.conf import settings
from django.shortcuts import render, redirect
from django.views import View
from django.contrib.auth import login
from django_redis import get_redis_connection

from mall_30.utils.response_code import RETCODE
from .utils import check_openid_sign, generate_openid_signature
from .models import OAuthQQUser
from users.models import User


logger = logging.getLogger('django')

class OAuthURLView(View):
    """提供QQ登录界面链接"""

    def get(self, request):

        # 提取前端用查询参数传入的next参数:记录用户从哪里去到login界面
        next = request.GET.get('next', '/')
        # QQ_CLIENT_ID = '101518219'
        # QQ_CLIENT_SECRET = '418d84ebdc7241efb79536886ae95224'
        # QQ_REDIRECT_URI = 'http://www.meiduo.site:8000/oauth_callback'
        # oauth = OAuthQQ(client_id='appid', client_secret='appkey', redirect_uri='授权成功回调url', state='记录来源')
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)
        # 拼接QQ登录连接
        # https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=123&redirect_uri=xxx&state=next
        login_url = oauth.get_qq_url()
        # print(login_url)
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class OAuthUserView(View):
    """qq登录后回调"""

    # http: // www.meiduo.site: 8000 / oauth_callback /?code = ECC8D8C60E5C0EE7448EEA7D621FFF42 & state = % 2
    # F
    def get(self, request):

        # 获取数据
        state = request.GET.get('state', '/')
        code = request.GET.get('code')

        # 创建qq登录SDK对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 获取用户的access_token
            access_token = oauth.get_access_token(code)

            #获取用户的openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': RETCODE.SERVERERR, 'errmsg': 'QQ服务器不可用'})

        # 校验
        if not openid:
            return http.HttpResponseForbidden('获取不到openid')

        # 判断用户是否已经注册
        try:
            oauth_qq = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            openid = generate_openid_signature(openid)
            return render(request, 'oauth_callback.html', {'openid':openid})

        else:
            # 响应
            user = oauth_qq.user
            login(request, user)

            response = redirect(state)
            response.set_cookie('username', user.username, 300)

            return response


    def post(self, request):
        """qq绑定界面"""

        #获取参数
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')

        # 校验
        if all([mobile, password, sms_code, openid]) is False:
            return http.HttpResponseForbidden('缺少必传的参数')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('手机号格式有误')

        if not re.match(r'[a-zA-Z0-9]{8,20}$', password):
            return http.HttpResponseForbidden('密码格式有误')

        #  短信验证
        redis_conn = get_redis_connection('verify_code')

        sms_code_redis = redis_conn.get('sms_code_%s'% mobile)

        if sms_code_redis is None or sms_code_redis.decode() != sms_code:
            return http.HttpResponseForbidden('短信验证码错误')

        # openid校验
        openid = check_openid_sign(openid)

        if openid is None:
            return http.HttpResponseForbidden('openid无效')

        # 绑定用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)

        else:
            if user.check_password(password) is False:
                return http.HttpResponseForbidden('帐号或者密码错误')

        OAuthQQUser.objects.create(
            user=user,
            openid=openid
        )

        # 状态保持
        login(request, user)

        # 响应
        response = redirect(request.GET.get('state'))

        response.set_cookie('username', user.username, 300)

        return response